package org.prj;

import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import java.io.*;
import groovy.lang.Binding;
import groovy.util.GroovyScriptEngine;
import groovy.util.ResourceException;
import groovy.util.ScriptException;

import org.slf4j.*;

import com.avaje.ebean.EbeanServer;
import com.avaje.ebean.EbeanServerFactory;
import com.avaje.ebean.config.DataSourceConfig;
import com.avaje.ebean.config.ServerConfig;

/** 
 * A servlet context listener to load and/or unload any Groovy scripts.
 *
 * @author Zemian Deng
 */
public class GroovyContextListener implements ServletContextListener {
	private static Logger logger = LoggerFactory.getLogger(GroovyContextListener.class);
	private String[] initScripts;
	private String[] destroyScripts;
	private String[] voScripts;
	private GroovyScriptEngine scriptEngine;
	public static EbeanServer server;
	

	@Override
	public void contextInitialized(ServletContextEvent sce) {
		ServletContext ctx = sce.getServletContext();

		String initScriptsStr = ctx.getInitParameter("initScripts");
		if (initScriptsStr != null && !initScriptsStr.trim().equals(""))
			initScripts = initScriptsStr.split(",");
		String destroyScriptsStr = ctx.getInitParameter("destroyScripts");
		if (destroyScriptsStr != null && !destroyScriptsStr.trim().equals(""))
			destroyScripts = destroyScriptsStr.split(",");
		String voScriptsStr = ctx.getInitParameter("voScripts");
		if (voScriptsStr != null && !voScriptsStr.trim().equals(""))
			voScripts = voScriptsStr.split(",");
		

		try {
			String webappDir = ctx.getRealPath("");
			String[] dirs = new String[] { webappDir };
			scriptEngine = new GroovyScriptEngine(dirs);
			
			//scriptEngine.getGroovyClassLoader()

			if (initScripts != null) {
				Binding binding = createBinding(ctx);
				for (String filename : initScripts)
					runScript(filename, binding);
			}
		} catch (Exception e) {
			throw new RuntimeException("Failed to init webapp with scripts.", e);
		}
		
//		ServerConfig config = new ServerConfig();
//
//		config.setName("test");
//
//		config.loadFromProperties();
//
//		DataSourceConfig postgresDb = new DataSourceConfig();
//		postgresDb.setDriver("org.h2.Driver");
//		postgresDb.setUsername("admin");
//		postgresDb.setPassword("admin");
//		postgresDb.setUrl("jdbc:h2:tcp://localhost/Users/dmac/Desktop/test2;DB_CLOSE_DELAY=-1;MVCC=true ");
//		postgresDb.setHeartbeatSql("select 1");
//		  
//		config.setDataSourceConfig(postgresDb);

//		if (voScripts != null) {
//			for (String filename : voScripts)
//				try {
//					if (filename.startsWith("/"))
//						filename = filename.substring(1);
//					
//					Class c=scriptEngine.loadScriptByName(filename);
//					config.addClass(c);
//				} catch (ResourceException | ScriptException e) {
//					// TODO Auto-generated catch block
//					e.printStackTrace();
//				}
//		}
//		
//		//config.addClass(Customer.class);
//
//		config.setDefaultServer(true);
//		 
		
		  
		// create the EbeanServer instance
//		server=EbeanServerFactory.create(config);
	}

	@Override
	public void contextDestroyed(ServletContextEvent sce) {
		try {
			ServletContext ctx = sce.getServletContext();
			if (destroyScripts != null) {
				Binding binding = createBinding(ctx);
				for (String filename : destroyScripts)
					runScript(filename, binding);
			}
		} catch (Exception e) {
			throw new RuntimeException("Failed to destroy webapp with scripts.", e);
		}
	}

	private Binding createBinding(ServletContext ctx) {
		Logger scriptLogger = LoggerFactory.getLogger(GroovyContextListener.class.getName() + "_script");
		Binding binding = new Binding();
		binding.setVariable("logger", scriptLogger);
		binding.setVariable("servletContext", ctx);
		//binding.setVariable("ebean", server);
		return binding;
	}

	private void runScript(String filename, Binding binding) throws Exception {
		if (filename.startsWith("/"))
			filename = filename.substring(1);
		logger.info("Running destroy script: " + filename);
		scriptEngine.run(filename, binding);
	}
}
